home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / Examples / USBSampleStorageDriver / UnitTableDriver / USB_ClassDriverAccess.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-25  |  5.8 KB  |  250 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        USB_ClassDriverAccess.c
  3.  
  4.     Contains:    All routines that directly access the USB Class Driver.
  5.  
  6.     Version:    1.0
  7.  
  8.     Copyright:    © 1999-2000 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #include "USB_ClassDriverAccess.h"
  13. #include "USB_ManualEjectSupport.h"
  14. #include "USB_StdCommands.h"
  15.  
  16. static StorageClassDispatchTablePtr            gItsTheDispatchTable = nil;        // The class's dispatch table
  17.  
  18. // This parameter block is used by the insternal state machines
  19. // to allow them to perform device requests which are transparent outside this module
  20. static IntDriveRequestPB                     gInternalRequestPB[2];
  21.  
  22. // Purposes for the Internal PBs
  23. enum
  24. {
  25.     kGeneralUsagePB        = 0,
  26.     kManualEjectPB        = 1
  27. };
  28.  
  29. static    Boolean        ManualEjectInProgess = false;
  30. static    Boolean        GeneralIORequestWaiting = false;
  31.  
  32. #pragma mark --
  33. Boolean IsClassDispatchTableValid( void )
  34. {
  35.     if ( gItsTheDispatchTable != nil )
  36.     {
  37.         return true;
  38.     }
  39.     
  40.     return false;
  41. }
  42.  
  43. void SetClassDispatchTable( StorageClassDispatchTablePtr newValue )
  44. {
  45.     if ( newValue != nil )
  46.     {
  47.         if ( newValue->dispatchTableVersion == kDispatchTableVersion )
  48.         {
  49.             gItsTheDispatchTable = newValue;
  50.         }
  51.         else
  52.         {
  53.             gItsTheDispatchTable = nil;
  54.         }
  55.     }
  56.     else
  57.     {
  58.         gItsTheDispatchTable = nil;
  59.     }
  60. }
  61.  
  62. OSStatus InitializeClassAccess( void )
  63. {
  64.     OSStatus status;
  65.     
  66.     status = ((gItsTheDispatchTable)->pStorageInitialize)();
  67.     return status;
  68. }
  69.  
  70. OSStatus TerminateClassAccess( void )
  71. {
  72.     OSStatus status = noErr;
  73.  
  74.     if(gItsTheDispatchTable != nil)
  75.     {
  76.         status = ((gItsTheDispatchTable)->pStorageTerminate)();
  77.     }
  78.     
  79.     gItsTheDispatchTable = nil;
  80.     return status;
  81. }
  82.  
  83. OSStatus SendClassStatusCall( UInt32 selectorCode, void *dataBuffer )
  84. {
  85.     OSStatus status;
  86.  
  87.     status = ((gItsTheDispatchTable)->pStorageStatus)(selectorCode, dataBuffer);
  88.     return status;
  89. }
  90.  
  91. OSStatus SendClassControlCall( UInt32 selectorCode, void *dataBuffer )
  92. {
  93.     OSStatus status;
  94.  
  95.     status = ((gItsTheDispatchTable)->pStorageControl)(selectorCode, dataBuffer);
  96.     return status;
  97. }
  98.  
  99. #pragma mark --
  100.  
  101. // Functions for handling allocation of Parameter Blocks for requests
  102. IntDriveRequestPBPtr    GetDriveInternalPB( void )
  103. {
  104.     if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
  105.     {
  106.         // The PB is in use, return nil
  107.         return nil;
  108.     }
  109.     
  110.     CancelManualEjectInterrupt();
  111.     BlockZero( &gInternalRequestPB[kGeneralUsagePB], sizeof (IntDriveRequestPB));
  112.     gInternalRequestPB[kGeneralUsagePB].inUse = true;
  113.     return &gInternalRequestPB[kGeneralUsagePB];
  114. }
  115.  
  116. void FreeInternalPB( IntDriveRequestPBPtr intDrivePB )
  117. {
  118.     intDrivePB->inUse = false;
  119.     ResetManualEjectInterrupt();
  120. }
  121.  
  122. Boolean IsCommandPending( void )
  123. {
  124.     return ( gInternalRequestPB[kGeneralUsagePB].inUse || gInternalRequestPB[kManualEjectPB].inUse);
  125. }
  126.  
  127. // Functions for handling allocation of Parameter Blocks for requests
  128. IntDriveRequestPBPtr    GetManualEjectPB( void )
  129. {
  130.     if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
  131.     {
  132.         // The PB is in use, return nil
  133.         return nil;
  134.     }
  135.     
  136.     BlockZero( &gInternalRequestPB[kManualEjectPB], sizeof (IntDriveRequestPB));
  137.     gInternalRequestPB[kManualEjectPB].inUse = true;
  138.     return &gInternalRequestPB[kManualEjectPB];
  139. }
  140.  
  141. void FreeManualEjectPB( IntDriveRequestPBPtr intDrivePB )
  142. {
  143.     intDrivePB->inUse = false;
  144. }
  145.  
  146. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. // Prevent and Allow Removal 
  148. // All functions and variables needed to handle setting the
  149. // ability to eject the media in the attached device.
  150. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  151. // Send Command to device
  152. OSStatus SendDeviceRequest( StorageExecuteCommandPB *commandPB )
  153. {
  154.     OSStatus    status = offLinErr;
  155.  
  156.     if (gItsTheDispatchTable)
  157.     {
  158.         if ( commandPB == &gInternalRequestPB[kGeneralUsagePB].executePB )
  159.         {
  160.             // This is the general use PB, check if there is a manual
  161.             // eject request already in progress.
  162.             if ( ManualEjectInProgess == true )
  163.             {
  164.                 GeneralIORequestWaiting = true;
  165.                 return kRequestPending;
  166.             }
  167.         }
  168.         else
  169.         {
  170.             if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
  171.             {
  172.                 // There is IO going on, return an error and do not try
  173.                 // to send the Manual Eject PB.
  174.                 return ioErr;
  175.             }
  176.             else
  177.             {
  178.                 ManualEjectInProgess = true;
  179.             }
  180.         }
  181.  
  182.     
  183.         status = (gItsTheDispatchTable->pStorageExecuteCmd)(commandPB);
  184.     }
  185.  
  186.     return status;
  187. }
  188.  
  189. // Completion routine for these commands
  190. void DeviceRequestCompletion(void *thePB)
  191. {
  192.     IntDriveRequestPBPtr    requestPB;
  193.     Boolean                    isManEject = false;
  194.     
  195.     requestPB = (IntDriveRequestPBPtr) thePB;
  196.     if ( requestPB == &gInternalRequestPB[kManualEjectPB])
  197.     {
  198.         isManEject = true;
  199.         ManualEjectInProgess = false;
  200.     }
  201.     else
  202.     {
  203.         isManEject = false;
  204.     }
  205.     
  206.     requestPB->status = requestPB->executePB.status;
  207.     
  208.     if ( requestPB->executePB.autoStatusIsValid == true )
  209.     {
  210.         requestPB->autoStatusIsValid = false;
  211.         //requestPB->autoStatusIsValid = theDrivePB->executePB.autoStatusIsValid;
  212.         requestPB->autoStatus[0] = requestPB->executePB.autoStatus[0];
  213.         requestPB->autoStatus[1] = requestPB->executePB.autoStatus[1];
  214.     }
  215.  
  216.     if ( (isManEject == true) && ( GeneralIORequestWaiting == true ))
  217.     {
  218.         OSStatus    theStatus = noErr;
  219.         
  220.         GeneralIORequestWaiting = false;
  221.         FreeManualEjectPB( &gInternalRequestPB[kManualEjectPB] );
  222.         theStatus = SendDeviceRequest( &gInternalRequestPB[kGeneralUsagePB].executePB );
  223.         if ( theStatus != kRequestPending )
  224.         {
  225.             gInternalRequestPB[kGeneralUsagePB].executePB.status = gInternalRequestPB[kGeneralUsagePB].status = theStatus;
  226.             (*((InternalCompletionProcPtr) gInternalRequestPB[kGeneralUsagePB].completionProc)) ( &gInternalRequestPB[kGeneralUsagePB] );
  227.         }
  228.     }
  229.     else
  230.     {
  231.         (*((InternalCompletionProcPtr) requestPB->completionProc)) ( requestPB );
  232.     }
  233. }
  234.  
  235. OSStatus AbortPendingCommand( void )
  236. {
  237.     OSStatus    status = noErr;
  238.     
  239.     if ( gInternalRequestPB[kGeneralUsagePB].inUse == true )
  240.     {
  241.         // We have a pending command, Go ahead and Abort it
  242.         //SysDebugStr("\pWatchDog timer went off");
  243.         
  244.         status = ((gItsTheDispatchTable)->pStorageControl)(kUSBStorageControlAbortCommand, &gInternalRequestPB[kGeneralUsagePB].executePB);
  245.     }
  246.  
  247.     return status;
  248. }
  249.  
  250.